home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_06 / bank.c < prev    next >
Text File  |  1995-01-01  |  7KB  |  298 lines

  1. /*
  2.     BANK.C
  3.  
  4.     28-jun-88, Marc Savary, Ad Lib Inc.
  5.  
  6.     Timbre Bank Manager.
  7.  
  8.     Refer to PLAY.C for compilation instructions.
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <fcntl.h>
  13.  
  14. #include "bank.h"
  15.  
  16.  
  17. #define TIMBRE_NAME_SIZE    9
  18. #define TIMBRE_DEF_LEN        28
  19. #define TIMBRE_DEF_SIZE    (TIMBRE_DEF_LEN * sizeof( int))
  20. #define MAJOR_VERSION        1
  21. #define MINOR_VERSION        0
  22.  
  23. #ifdef LATTICE
  24. extern char * getmem();
  25. extern long lseek();
  26. #endif
  27.  
  28. #ifdef MICROSOFT
  29. #include  <malloc.h>
  30. #include  <string.h>
  31. #include  <io.h>
  32. #include  <stdio.h>
  33. #include  <sys\types.h>
  34. #include  <sys\stat.h>
  35. #define  open(x,y)      open(x,y,S_IWRITE)
  36. #define  rlsmem(x,y)    free(x)
  37. #define  getmem(x)      malloc(x)
  38. #define  setmem(x,y,z)  memset(x,z,y)
  39. #define  movmem(x,y,z)  memmove(y,x,z)
  40. #endif
  41.  
  42.  
  43.  
  44.  
  45.  
  46. /*
  47.     Open the timbre bank 'bankName'. If does not exist, and
  48.     'creatFlag' is != 0, create it.
  49.  
  50.     Return a pointer to the descriptor, or NULL if error.
  51. */
  52. BankPtr OpenBank( bankName, createFlag)
  53.     char * bankName;
  54.     {
  55.     int file;
  56.     BankRec * bP;
  57.  
  58.     bP = (BankRec *) getmem( sizeof( BankRec));
  59.     if( NULL == bP)
  60.         return NULL;
  61.     file = open( bankName, O_RDWR + O_RAW);
  62.     if( file == -1) {
  63.         if( ! createFlag || -1 == ( file = CreateBank( bankName))) {
  64.             rlsmem( bP, sizeof( BankRec));
  65.             return NULL;
  66.             }
  67.         }
  68.     bP->fileId = file;
  69.     bP->inMemFlag = 0;
  70.     bP->modified = 0;
  71.     return bP;
  72.     }    /* OpenBank() */
  73.  
  74.  
  75. /*
  76.     Close the already opened bank. If the bank has beed modified,
  77.     write the modifications to file.
  78. */
  79. int CloseBank( bankPtr)
  80.     BankPtr bankPtr;
  81.     {
  82.     int len;
  83.  
  84.     if( bankPtr->modified) {
  85.         lseek( bankPtr->fileId, 0L, 0);
  86.         len = sizeof( TimFileBank) + bankPtr->timbBank->nrTimbre
  87.                     * ( TIMBRE_DEF_SIZE + TIMBRE_NAME_SIZE);
  88.         write( bankPtr->fileId, (char *) bankPtr->timbBank, len);
  89.         }
  90.     close( bankPtr->fileId);
  91.     if( bankPtr->inMemFlag) {
  92.         rlsmem( bankPtr->timbBank, len);
  93.         }
  94.     rlsmem( bankPtr, sizeof( BankRec));
  95.     return 1;
  96.     }    /* CloseBank() */
  97.  
  98.  
  99.  
  100. /*
  101.     Load all the bank in memory, for fast access. Allocate required
  102.     memory.
  103.     return 0 if error.
  104. */
  105. int LoadBank( bankPtr)
  106.     BankPtr bankPtr;
  107.     {
  108.     TimFileBank tB, * tBPtr;
  109.     int res, len, i;
  110.     long pos;
  111.  
  112.     pos = lseek( bankPtr->fileId, 0L, 0);
  113.     res = read( bankPtr->fileId, (char *) &tB, sizeof( TimFileBank));
  114.     len = tB.nrTimbre * (TIMBRE_NAME_SIZE + TIMBRE_DEF_SIZE);
  115.     len += sizeof( TimFileBank);
  116.     tBPtr = ( TimFileBank *) getmem( len);
  117.     if( tBPtr == NULL)
  118.         return 0;
  119.     pos = lseek( bankPtr->fileId, 0L, 0);
  120.     read( bankPtr->fileId, (char *) tBPtr, len);
  121.     bankPtr->timbBank = tBPtr;
  122.     bankPtr->inMemFlag = 1;
  123.     return 1;
  124.     }    /* LoadBank() */
  125.  
  126.  
  127. /*
  128.     Return the timbre definition in 'timbreDefPtr'.
  129.     If 'timbreName' is not an empty string, search for in the index of
  130.     'bankPtr' and set 'timbreIndex' to the found position value.
  131.     If 'timbreName' is an empty string, use 'timbreIndex' as position.
  132. */
  133. int GetTimbre( timbreName, timbreIndex, timbreDefPtr, bankPtr)
  134.     char * timbreName;            /* name of timbre def. to return */
  135.     int * timbreIndex;            /* used if 'timbreName' == "" */
  136.     int * timbreDefPtr;            /* array for save to timbre def. */
  137.     BankPtr bankPtr;            /* timbre bank ref. */
  138.     {
  139.     if( bankPtr->inMemFlag)
  140.         return InMemGetTimbre( timbreName, timbreIndex, timbreDefPtr, bankPtr);
  141.     else
  142.         return InFileGetTimbre( timbreName, timbreIndex, timbreDefPtr, bankPtr);
  143.     }    /* GetTimbre() */
  144.  
  145.  
  146. /*
  147.     If 'timbreName' exists in the bank, replace its definition by 'timbreDef'.
  148.     If not, add definition to the end of the bank.
  149.     Return in 'timbIndex' the relative position of timbre.
  150. */
  151. int AddTimbre( timbreName, timbIndex, timbreDef, bankPtr)
  152.     char * timbreName;
  153.     int * timbIndex;
  154.     int * timbreDef;
  155.     BankPtr bankPtr;
  156.     {
  157.     int tmpDef[ TIMBRE_DEF_LEN];
  158.     int index, mv, oldLen, len, nlen, i;
  159.     char * defPtr, * dest;
  160.     TimFileBank * tb1, * tb2;
  161.  
  162.     if( ! bankPtr->inMemFlag && ! LoadBank( bankPtr))
  163.         return 0;
  164.  
  165.     if( GetTimbre( timbreName, &index, tmpDef, bankPtr)) {
  166.         /* replace it ... */
  167.         defPtr = (char *)bankPtr->timbBank + bankPtr->timbBank->offsetDef
  168.                                     + index * TIMBRE_DEF_SIZE;
  169.         movmem( timbreDef, defPtr, TIMBRE_DEF_SIZE);
  170.         *timbIndex= index;
  171.         }
  172.     else {
  173.         /* add to the end. */
  174.         tb1 = bankPtr->timbBank;
  175.         *timbIndex = tb1->nrTimbre;
  176.         oldLen = tb1->nrTimbre * ( TIMBRE_NAME_SIZE + TIMBRE_DEF_SIZE)
  177.                                     + sizeof( TimFileBank);
  178.         len = oldLen + TIMBRE_NAME_SIZE + TIMBRE_DEF_SIZE;
  179.         tb2 = ( TimFileBank *) getmem( len);
  180.         if( tb2 == NULL)
  181.             return 0;
  182.         mv = tb1->nrTimbre * TIMBRE_NAME_SIZE + sizeof( TimFileBank);
  183.         dest = (char *) tb2;
  184.         movmem( tb1, dest, mv);
  185.         dest += mv;
  186.         nlen= strlen( timbreName);
  187.         movmem( timbreName, dest, TIMBRE_NAME_SIZE);
  188.         setmem( dest + nlen, TIMBRE_NAME_SIZE - nlen, 0);
  189.         dest += TIMBRE_NAME_SIZE;
  190.         mv = tb1->nrTimbre * TIMBRE_DEF_SIZE;
  191.         movmem( (char *)tb1 + tb1->offsetDef, dest, mv);
  192.         dest += mv;
  193.         movmem( timbreDef, dest, TIMBRE_DEF_SIZE);
  194.         rlsmem( tb1, oldLen);
  195.         tb2->offsetDef += TIMBRE_NAME_SIZE;
  196.         tb2->nrTimbre++;
  197.         bankPtr->timbBank = tb2;
  198.         }
  199.     bankPtr->modified = 1;
  200.     return 1;
  201.     }    /* AddTimbre() */
  202.  
  203.  
  204.  
  205.  
  206. /*
  207.     Create a new timbre bank and initialize the header.
  208.     Return the file id.
  209. */
  210. static int CreateBank( bankName)
  211.     char * bankName;
  212.     {
  213.     int file;
  214.     TimFileBank tB;
  215.  
  216.     file = open( bankName, O_RDWR + O_RAW + O_CREAT);
  217.     if( -1 == file)
  218.         return 0;
  219.  
  220.     tB.majorVersion     = MAJOR_VERSION;
  221.     tB.minorVersion = MINOR_VERSION;
  222.     tB.nrTimbre = 0;
  223.     tB.offsetDef = sizeof( TimFileBank);
  224.     write( file, (char *) &tB, sizeof( TimFileBank));
  225.  
  226.     /* Lattice C Bug: lseek does not work on newly created files !! ??? */
  227.     close( file);
  228.     file = open( bankName, O_RDWR + O_RAW);
  229.     return file;
  230.     }    /* CreateBank() */
  231.  
  232.  
  233.  
  234. /*
  235.     Do the work of 'GetTimbre()' when bank is not in memory.
  236. */
  237. static int InFileGetTimbre( timbreName, timbreIndex, timbreDefPtr, bankPtr)
  238.     char * timbreName;
  239.     int * timbreIndex;
  240.     int * timbreDefPtr;
  241.     BankPtr bankPtr;
  242.     {
  243.     TimFileBank tB;
  244.     char indexName[ TIMBRE_NAME_SIZE];
  245.     int i;
  246.  
  247.     lseek( bankPtr->fileId, 0L, 0);
  248.     read( bankPtr->fileId, (char *) &tB, sizeof( TimFileBank));
  249.     i = *timbreIndex;
  250.     if( *timbreName) {
  251.         for( i = 0; i < tB.nrTimbre; i++) {
  252.             read( bankPtr->fileId, indexName, TIMBRE_NAME_SIZE);
  253.             if( 0 == strcmp( timbreName, indexName))
  254.                 break;
  255.             }
  256.         }
  257.     if( i >= tB.nrTimbre)
  258.         return 0;
  259.     lseek( bankPtr->fileId,
  260.             (long)( tB.offsetDef + i * TIMBRE_DEF_SIZE), 0);
  261.     read( bankPtr->fileId, (char *) timbreDefPtr, TIMBRE_DEF_SIZE);
  262.     *timbreIndex = i;
  263.     return 1;
  264.     }    /* InFileGetTimbre() */
  265.  
  266.  
  267. /*
  268.     Do the work of 'GetTimbre()' when bank is in memory.
  269. */
  270. static int InMemGetTimbre( timbreName, timbreIndex, timbreDefPtr, bankPtr)
  271.     char * timbreName;
  272.     int * timbreIndex;            /* in/out */
  273.     int * timbreDefPtr;
  274.     BankPtr bankPtr;
  275.     {
  276.     TimFileBank tB;
  277.     char * defPtr, * iP;
  278.     int i, nrTimbre;
  279.  
  280.     i = * timbreIndex;
  281.     nrTimbre = bankPtr->timbBank->nrTimbre;
  282.     iP = (char *)bankPtr->timbBank + sizeof( TimFileBank);
  283.     if( *timbreName) {
  284.         for( i = 0; i < nrTimbre; i++, iP += TIMBRE_NAME_SIZE)
  285.             if( 0 == strcmp( timbreName, iP))
  286.                 break;
  287.         }
  288.     if( i >= nrTimbre)
  289.         return 0;
  290.     defPtr = (char *)bankPtr->timbBank + bankPtr->timbBank->offsetDef;
  291.     movmem( defPtr + i * TIMBRE_DEF_SIZE, timbreDefPtr, TIMBRE_DEF_SIZE);
  292.     *timbreIndex = i;
  293.     return 1;
  294.     }    /* InMemGetTimbre() */
  295.  
  296.  
  297.  
  298.